package org.atlantis.grosbeak.lang;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.security.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.atlantis.grosbeak.castor.Castors;
import org.atlantis.grosbeak.lang.fruit.Fruiting;
import org.atlantis.grosbeak.lang.fruit.FruitingException;
import org.atlantis.grosbeak.lang.fruit.MirrorFruiting;
import org.atlantis.grosbeak.lang.inject.FailToInjectException;
import org.atlantis.grosbeak.lang.inject.FieldInjector;
import org.atlantis.grosbeak.lang.inject.Injecting;
import org.atlantis.grosbeak.lang.inject.SetterInjector;

/**
 * 为Java的反射机制提供更多简单的操作。
 * 
 * @author <a href="mailto:seenoevil.cn@gmail.com">SeeNoEvil</a>
 * 
 */
public class Mirror<T> {

	/**
	 * 使用Mirror包裹一个类，从而得到更多操作方法。如：
	 * 
	 * <pre>
	 * Mirror.me(String.class);
	 * </pre>
	 * 
	 * @param <T>
	 *            类型。
	 * @param clazz
	 *            需要Mirror包裹的类型。
	 * @return Mirror对象。
	 */
	public static <T> Mirror<T> me(Class<T> clazz) {
		return (null == clazz) ? null : new Mirror<T>(clazz);
	}

	/**
	 * 包裹Mirror包裹一个对象，从而得到更多操作方法。如：
	 * 
	 * <pre>
	 * Mirror.me(new String());
	 * </pre>
	 * 
	 * @param <T>
	 *            对象的类型。
	 * @param t
	 *            需要Mirror包裹的对象。
	 * @return Mirror对象。
	 */
	@SuppressWarnings("unchecked")
	public static <T> Mirror<T> me(T t) {
		if (null == t)
			return null;
		return (Mirror<T>) me(t.getClass());
	}

	private Class<T> clazz;

	private Mirror(Class<T> clazz) {
		this.clazz = clazz;
	}

	/**
	 * 得到Mirror封装的类型。如：Mirror.me(String.class).getMirrorType()得到的就是String.class。
	 * 
	 * @return 得到Mirror封装的类型。
	 */
	public Class<T> getMirrorType() {
		return clazz;
	}

	/**
	 * 得到当前类型的抽象描述。如：Mirror.me(List.class).getAbstractDesc()得到的就是Collection.
	 * class。如果没有得到抽象描述，则返回自己本身。
	 * 
	 * @return 当前类型的抽象描述。
	 */
	public Class<?> getAbstractDesc() {
		if (isEnum()) {
			return Enum.class;
		} else if (clazz.isArray()) {
			return Array.class;
		} else if (isString()) {
			return String.class;
		} else if (is(Class.class)) {
			return Class.class;
		} else if (asString()) {
			return CharSequence.class;
		} else if (isNumber()) {
			return Number.class;
		} else if (isBoolean()) {
			return Boolean.class;
		} else if (isChar()) {
			return Character.class;
		} else if (as(Map.class)) {
			return Map.class;
		} else if (as(Collection.class)) {
			return Collection.class;
		} else if (as(Calendar.class)) {
			return Calendar.class;
		} else if (as(Timestamp.class)) {
			return Timestamp.class;
		} else if (as(java.sql.Time.class)) {
			return java.sql.Time.class;
		} else if (as(java.sql.Date.class)) {
			return java.sql.Date.class;
		} else if (as(java.util.Date.class)) {
			return java.util.Date.class;
		}
		return clazz;
	}

	/**
	 * 通过字段名得到Getter方法。<br>
	 * 例如：字段名是name，那么首先查找getName()，如果没有就查找name()，如果还没有就抛出异常。<br>
	 * 注：如果name是一个boolean类型的字段，那么还会查找isName()。
	 * 
	 * @param fieldName
	 *            字段名。
	 * @return 对应字段名的Getter方法。
	 * 
	 * @throws FailToMirrorException
	 *             当获取不到指定方法时抛出。
	 */
	public Method getGetter(String fieldName) throws FailToMirrorException {
		String getter = getGetterName(fieldName);
		String booleanGetter = getBooleanGetterName(fieldName);
		try {
			try {
				try {
					return clazz.getMethod(getter);
				} catch (NoSuchMethodException e) {
					Method method = clazz.getMethod(booleanGetter);
					if (!Mirror.me(method.getReturnType()).isBoolean())
						throw new NoSuchMethodException();
					return method;
				}
			} catch (NoSuchMethodException e) {
				return clazz.getMethod(fieldName);
			}
		} catch (Exception e) {
			// TODO
			// 这里把异常都封装到了一个FailToMirrorException中，这样做可以使使用者的代码更简单，但是好不好呢？还需要思考！
			throw Exceptions.makeThrow(FailToMirrorException.class, e,
					"Can't find getter method for [%s] from [%s].", fieldName,
					clazz.getName());
		}

	}

	/**
	 * 通过字段得到Getter方法。<br>
	 * 例如：字段名是name，那么首先查找getName()，如果没有就查找name()，如果还没有就抛出异常。<br>
	 * 注：如果name是一个boolean类型的字段，那么还会查找isName()。
	 * 
	 * @param field
	 *            字段。
	 * @return 对应该字段的Getter方法。
	 * 
	 * @throws FailToMirrorException
	 *             当获取不到指定方法时抛出。
	 * 
	 * @see #getGetter(String)
	 */
	public Method getGetter(Field field) throws FailToMirrorException {
		return getGetter(field.getName());
	}

	/**
	 * 通过字段和需要的参数类型得到Setter方法。<br>
	 * 例如：字段名是name，那么首先查找setName(xxx)，如果没有就查找name(xxx)，如果还没有就抛出异常。<br>
	 * 
	 * @param fieldName
	 *            字段名。
	 * @param paramType
	 *            Setter方法所需参数的类型。
	 * @return 对应字段名的Getter方法。
	 * 
	 * @throws FailToMirrorException
	 *             当获取不到指定方法时抛出。
	 */
	public Method getSetter(String fieldName, Class<?> paramType)
			throws FailToMirrorException {
		String setter = getSetterName(fieldName);
		String booleanSetter = getBooleanSetterName(fieldName);
		try {
			try {
				if (Mirror.me(paramType).isBoolean())
					return clazz.getMethod(booleanSetter, paramType);
				else
					return clazz.getMethod(setter, paramType);
			} catch (NoSuchMethodException e) {
				return clazz.getMethod(fieldName, paramType);
			}
		} catch (Exception e) {
			// TODO
			// 这里把异常都封装到了一个FailToMirrorException中，这样做可以使使用者的代码更简单，但是好不好呢？还需要思考！
			throw Exceptions
					.makeThrow(
							FailToMirrorException.class,
							e,
							"Can't find setter method for [%s] with parameter [%s] from [%s].",
							fieldName, paramType.getName(), clazz.getName());
		}
	}

	/**
	 * 通过字段名和需要的参数类型得到Setter方法。<br>
	 * 例如：字段名是name，那么首先查找setName(xxx)，如果没有就查找name(xxx)，如果还没有就抛出异常。<br>
	 * 
	 * @param field
	 *            字段。
	 * @param paramType
	 *            Setter方法所需参数的类型。
	 * @return 对应字段的Setter方法。
	 * 
	 * @throws FailToMirrorException
	 *             当获取不到指定方式时抛出
	 * 
	 * @see #getSetter(String, Class)
	 */
	public Method getSetter(Field field) throws FailToMirrorException {
		return getSetter(field.getName(), field.getType());
	}

	/**
	 * 根据一个字段名尝试找出一组可能是Setter方法的方法。<br>
	 * 可能的Setter方法：
	 * <ul>
	 * <li>setFieldName(xxx)</li>
	 * <li>fieldName(xxx)</li>
	 * </ul>
	 * 
	 * @param fieldName
	 *            字段名。
	 * @return 该字段可能的Setter方法数组。
	 */
	public Method[] tryToFindSetters(String fieldName) {
		String setter = getSetterName(fieldName);
		String booleanSetter = getBooleanSetterName(fieldName);
		ArrayList<Method> ms = new ArrayList<Method>();
		for (Method m : clazz.getMethods()) {
			if (Modifier.isStatic(m.getModifiers())
					|| m.getParameterTypes().length != 1)
				continue;
			if (m.getName().equals(setter) || m.getName().equals(booleanSetter)
					|| m.getName().equals(fieldName))
				ms.add(m);
		}
		return ms.toArray(new Method[ms.size()]);
	}

	/**
	 * 根据一个字段名尝试找到一组可能是Getter方法的方法（仅根据字段名判断，不会根据类型判断，如：
	 * String类型的字段也有可能会获得isFieldName()方法）。<br>
	 * 可能的Getter方法：
	 * <ul>
	 * <li>getFieldName()</li>
	 * <li>isFieldName()</li>
	 * <li>fieldName()</li>
	 * </ul>
	 * 
	 * @param fieldName
	 * @return
	 */
	public Method[] tryToFindGetters(String fieldName) {
		String getter = getGetterName(fieldName);
		String booleanGetter = getBooleanGetterName(fieldName);
		ArrayList<Method> ms = new ArrayList<Method>();
		for (Method m : clazz.getMethods()) {
			if (Modifier.isStatic(m.getModifiers())
					|| m.getParameterTypes().length != 0)
				continue;
			if (m.getName().equals(getter) || m.getName().equals(booleanGetter)
					|| m.getName().equals(fieldName))
				ms.add(m);
		}
		return ms.toArray(new Method[ms.size()]);
	}

	/**
	 * 根据字段名获取该字段的Getter方法名（对于非boolean类型的字段）。<br>
	 * 对于非boolean类型的字段的Getter方法名应该是：getFieldName。
	 * 
	 * @param fieldName
	 *            字段名。
	 * @return 该字段名对应的Getter方法名。
	 */
	public static String getGetterName(String fieldName) {
		return new StringBuilder("get").append(Strings.capitalize(fieldName))
				.toString();
	}

	/**
	 * 根据字段名获取该字段的Getter方法名（对于boolean类型的字段）<br>
	 * 对于boolean类型的字段的Getter方法名应该是：isFieldName。
	 * 
	 * @param fieldName
	 *            字段名。
	 * @return 该字段名对应的Getter方法名。
	 */
	public static String getBooleanGetterName(String fieldName) {
		if (Strings.startsWith(fieldName, "is"))
			fieldName = fieldName.substring(2);
		return new StringBuilder("is").append(Strings.capitalize(fieldName))
				.toString();
	}

	/**
	 * 根据字段名获取该字段的Setter方法名（对于非boolean类型的字段）。<br>
	 * 不管是不是boolean类型的字段，其Setter方法名都应该是：setFieldName。
	 * 
	 * @param fieldName
	 *            字段名。
	 * @return 该字段对应的Setter方法名。
	 */
	public static String getSetterName(String fieldName) {
		return new StringBuilder("set").append(Strings.capitalize(fieldName))
				.toString();
	}

	/**
	 * 根据字段名获取该字段的Setter方法名（如果字段名以is开头，那么会截去is）。<br>
	 * 不管是不是boolean类型的字段，其Setter方法名都应该是：setFieldName。<br>
	 * <b>注：</b>如果该字段是以is开头，那么会截去is后再生成Setter方法。如字段是isStudent，
	 * 那么其Setter方法名为setStudent。
	 * 
	 * @param fieldName
	 * @return
	 */
	public static String getBooleanSetterName(String fieldName) {
		if (Strings.startsWith(fieldName, "is"))
			fieldName = fieldName.substring(2);
		return new StringBuilder("set").append(Strings.capitalize(fieldName))
				.toString();
	}

	/**
	 * 根据字段名查找一个字段，这个字段可能是当前对象的类中的，也可能是其父类、祖父类中的，但不会在Object中查找。
	 * 
	 * @param fieldName
	 *            需要查找的字段。
	 * @return 字段的Field对象。
	 * 
	 * @throws FailToMirrorException
	 *             当获取不到指定字段时抛出
	 */
	public Field getField(String fieldName) throws FailToMirrorException {
		Class<?> theClazz = clazz;
		Field field = null;
		while (null != theClazz && theClazz != Object.class) {
			try {
				field = theClazz.getDeclaredField(fieldName);
				return field;
			} catch (NoSuchFieldException e) {
				theClazz = theClazz.getSuperclass();
			}
		}
		// TODO 这里把异常都封装到了一个FailToMirrorException中，这样做可以使使用者的代码更简单，但是好不好呢？还需要思考！
		throw Exceptions.makeThrow(FailToMirrorException.class,
				"Can't find the field [%s] from [%s] ant it's parent classes.",
				fieldName, clazz.getName());
	}

	/**
	 * 获取一个声明了指定注解的字段。只返回第一个。
	 * 
	 * @param <AN>
	 *            声明的注解的类型。
	 * @param annotation
	 *            声明的注解的类型。
	 * @return 第一个声明了指定注解的字段。
	 * 
	 * @throws FailToMirrorException
	 *             当获取不到指定字段时抛出
	 */
	public <AN extends Annotation> Field getField(Class<AN> annotation)
			throws FailToMirrorException {
		for (Field field : getFields())
			if (null != field.getAnnotation(annotation))
				return field;
		throw Exceptions.makeThrow(FailToMirrorException.class,
				"Can't find field [@%s] in class [%s] and it's parent classes",
				annotation.getName(), clazz.getName());
	}

	/**
	 * 获取所有的声明了指定注解的字段。
	 * 
	 * @param <AN>
	 *            声明的注解的类型。
	 * @param annotation
	 *            声明的注解类型。
	 * @return 声明了指定注解的字段数组。
	 */
	public <AN extends Annotation> Field[] getFields(Class<AN> annotation) {
		List<Field> fields = new LinkedList<Field>();
		for (Field field : getFields()) {
			if (null != field.getAnnotation(annotation))
				fields.add(field);
		}
		return fields.toArray(new Field[fields.size()]);
	}

	/**
	 * 获得当前对象中的所有字段，包括私有字段，父类字段，但不包括Object中的字段。
	 * 
	 * @return 当前对象（包括父类字段、祖父类字段……，但不包括Object中的字段）中的所有字段的数组。
	 */
	public Field[] getFields() {
		Class<?> theClazz = clazz;
		// 这里Map的主要作用是去重，因为子类和父类中可能存在字段名相同的字段。
		Map<String, Field> clear = new HashMap<String, Field>();
		while (null != theClazz && theClazz != Object.class) {
			Field[] fields = theClazz.getDeclaredFields();
			for (Field field : fields) {
				if (isIgnoreField(field))
					continue;
				if (clear.containsKey(field.getName()))
					continue;
				clear.put(field.getName(), field);
			}
			theClazz = theClazz.getSuperclass();
		}
		return clear.values().toArray(new Field[clear.size()]);
	}

	/**
	 * 获得当前类型的所有方法，包括私有方法，父类方法，但不包括Object中的方法（不会消除重）。
	 * 
	 * @return 当前对象（包括父类方法、祖父类方法……，但不包括Object中的方法）中的所有方法的数组。
	 */
	public Method[] getMethods() {
		Class<?> theClazz = clazz;
		List<Method> list = new LinkedList<Method>();
		while (null != theClazz && theClazz != Object.class) {
			Method[] methods = theClazz.getDeclaredMethods();
			for (Method method : methods)
				list.add(method);
			theClazz = theClazz.getSuperclass();
		}
		return list.toArray(new Method[list.size()]);
	}

	/**
	 * 获取当前类型的所有方法，包括私有方法，包括父类、祖父类……方法，递归查找到指定的类为止。 <br>
	 * 并且会按照方法名称消除重复的方法（有的方法是子类覆写父类的）。子类的方法优先。如：
	 * 
	 * <pre>
	 * class A{}
	 * class B extends A{}
	 * class C exnteds B{}
	 * class D extends C{}
	 * class E extends D{}
	 * class F extends E{}
	 * 那么Mirror.me(f.class).getAllDeclareMethods(B.class)返回的结果就是F、E、D、C中的所有方法。
	 * </pre>
	 * 
	 * @param top
	 *            指定的终止类。
	 * @return 所有方法的数组。
	 */
	public Method[] getAllDeclareMethods(Class<?> top) {
		Class<?> theClazz = clazz;
		Map<String, Method> clear = new HashMap<String, Method>();
		while (null != theClazz && theClazz != top) {
			Method[] methods = theClazz.getDeclaredMethods();
			for (Method method : methods) {
				String key = method.getName()
						+ Mirror.getParamsDesc(method.getParameterTypes());
				if (!clear.containsKey(key))
					clear.put(key, method);
			}
			theClazz = theClazz.getSuperclass();
		}
		return clear.values().toArray(new Method[clear.size()]);
	}

	/**
	 * 获取当前类型的所有方法，包括私有方法，包括父类方法，递归查找到Object为止。 <br>
	 * 并且会按照方法名称消除重复的方法（有的方法是子类覆写父类的）。子类的方法优先。
	 * 
	 * @return 所有方法的数组。
	 * 
	 * @see #getAllDeclareMethods(Class)
	 */
	public Method[] getAllDeclareMethods() {
		return getAllDeclareMethods(Object.class);
	}

	/**
	 * 获取所有静态方法。仅获取当前类型的所有静态方法，不包括父类的。
	 * 
	 * @return 当前对象的类型中的所有静态方法。
	 */
	public Method[] getStaticMethods() {
		List<Method> list = new LinkedList<Method>();
		for (Method method : clazz.getMethods()) {
			if (Modifier.isStatic(method.getModifiers())
					&& Modifier.isPublic(method.getModifiers()))
				list.add(method);
		}
		return list.toArray(new Method[list.size()]);
	}

	/**
	 * 为指定对象（obj）的指定字段（field）赋值（value）。不调用字段的setter方法，而是直接赋值（会自动进行类型转换）。
	 * 
	 * @param obj
	 *            需要赋值的对象。
	 * @param field
	 *            需要赋值的字段。
	 * @param value
	 *            值，如果为null那么数字和字符字段都会被设置成0。
	 * @throws FailToMirrorException
	 *             当设值失败时出现。
	 */
	public void setValue(Object obj, Field field, Object value)
			throws FailToMirrorException {
		if (!field.isAccessible())
			field.setAccessible(true);
		Mirror<?> me = Mirror.me(field.getType());
		try {
			if (null != value) {
				if (Castors.me().canCast(value.getClass(), me.getMirrorType()))
					value = Castors.me().castTo(value, me.getMirrorType());
			} else {
				if (me.isNumber())
					value = 0;
				else if (me.isChar())
					value = (char) 0;
			}
			field.set(obj, value);
		} catch (Exception e) {
			throw Exceptions.makeThrow(FailToMirrorException.class, e,
					"Fail to set value [%s] for [%s] from [%s], because '%s'.",
					value, field.getName(), clazz.getName(), e.getMessage());
		}
	}

	/**
	 * 为指定对象（obj）的指定字段（名为fieldName的字段）赋值（value）。优先调用字段的setter方法，
	 * 如果没有setter方法则直接赋值（不会自动使用类型转换，因为可能存在方法名相同而参数不同的Setter方法 - 即重载Setter方法，所以
	 * 必须通过value的类型来确定是使用哪一个Setter方法）。
	 * 
	 * @param obj
	 *            需要赋值的对象。
	 * @param fieldName
	 *            需要赋值的字段名。
	 * @param value
	 *            值。
	 * 
	 * @throws FailToMirrorException
	 *             当设值失败时出现。
	 * 
	 * @see #setValue(Object, Field, Object)
	 */
	public void setValue(Object obj, String fieldName, Object value)
			throws FailToMirrorException {
		try {
			getSetter(fieldName, value.getClass()).invoke(obj, value);
		} catch (Exception e) {
			try {
				Field field = getField(fieldName);
				setValue(obj, field, value);
			} catch (Exception e1) {
				throw Exceptions
						.makeThrow(
								FailToMirrorException.class,
								e1,
								"Fail to set value [%s] for [%s] from [%s], because '%s'.",
								value, fieldName, clazz.getName(), e1
										.getMessage());
			}
		}
	}

	/**
	 * 获取指定对象（obj）中的指定字段（field）的值，不使用Getter方法，直接获取。
	 * 
	 * @param obj
	 *            要从中获取字段值的对象。
	 * @param field
	 *            要获取值的字段。
	 * @return 字段值。
	 * 
	 * @throws FailToMirrorException
	 *             当不能获取值时出现
	 */
	public Object getValue(Object obj, Field field)
			throws FailToMirrorException {
		if (!field.isAccessible())
			field.setAccessible(true);
		try {
			return field.get(obj);
		} catch (Exception e) {
			throw Exceptions.makeThrow(FailToMirrorException.class, e,
					"Fail to get value from [%s] in [%s], because '%s'", field
							.getName(), clazz.getName(), e.getMessage());
		}
	}

	/**
	 * 获取指定对象（obj）中的指定字段（field）的值，优先采用Getter方法，如果没有Getter方法则直接获取。
	 * 
	 * @param obj
	 *            要从中获取字段值的对象。
	 * @param fieldName
	 *            要获取值的字段名称。
	 * @return 字段值。
	 * @throws FailToMirrorException
	 *             当不能获取值时出现
	 * @see #getValue(Object, Field)
	 */
	public Object getValue(Object obj, String fieldName)
			throws FailToMirrorException {
		try {
			return getGetter(fieldName).invoke(obj);
		} catch (Exception e) {
			try {
				Field field = getField(fieldName);
				return getValue(obj, field);
			} catch (Exception e1) {
				throw Exceptions.makeThrow(FailToMirrorException.class, e1,
						"Fail to get value from [%s] in [%s], because '%s'",
						fieldName, clazz.getName(), e1.getMessage());
			}
		}
	}

	/**
	 * 是否可将当前对象转换为指定类型。
	 * 
	 * @param type
	 *            指定类型。
	 * @return 是否可以转换。
	 */
	public boolean canCastTo(Class<?> type) {
		return Castors.me().canCast(clazz, type);
	}

	/**
	 * 知否可以直接将当前对象转换为指定类型（不使用转换器）。
	 * 
	 * @param type
	 *            指定类型。
	 * @return 是否可以转换。
	 */
	public boolean canCastToDirectly(Class<?> type) {
		return Castors.canCastDirectly(clazz, type);
	}

	/**
	 * 是否可以使用转换器把当前对象转换成指定类型。
	 * 
	 * @param type
	 *            指定类型。
	 * @return 是否可以转换。
	 */
	public boolean canCastToWithoutDirectly(Class<?> type) {
		return Castors.me().canCastWithoutDirectly(clazz, type);
	}

	/**
	 * 如果当前对象类型是原始类型，那么就返回该原始类型的包装类。否则返回null。
	 * 
	 * @return 如果当前对象是原始类型（如：int、char、boolean等），则返回原始类型的封装类（如：Integer、Charseter、
	 *         Boolean等），否则返回当前对象自己本身的类型。
	 */
	public Class<?> getWrapperClass() {

		/*
		 * 首先判断一下当前类型是否为基本类型。如果没有这个判断，直接进行下面的多个if的比较也可以，
		 * 这样的话如果如果不是基本类型，那么每次都要进行所有的比较就很消耗性能了。
		 */
		if (!clazz.isPrimitive()) {
			if (isPrimitiveNumber() || isBoolean() || isChar())
				return clazz;
		} else {
			if (isInt())
				return Integer.class;
			else if (isBoolean())
				return Boolean.class;
			else if (isChar())
				return Character.class;
			else if (isLong())
				return Long.class;
			else if (isFloat())
				return Float.class;
			else if (isByte())
				return Byte.class;
			else if (isShort())
				return Short.class;
			else if (isDouble())
				return Double.class;
		}
		return clazz;
	}

	/**
	 * 当前对象的类型的包装类是否为指定类型。如：
	 * 
	 * <pre>
	 * Mirror.me(int.class).isWrapperOf(Integer.class); // 为true。
	 * </pre>
	 * 
	 * @param type
	 *            包装类类型。
	 * @return 当前对象的类型的包装类是否为指定类型。
	 */
	public boolean isWrapperOf(Class<?> type) {
		return Mirror.me(type).getWrapperClass() == clazz;
	}

	/**
	 * 如果当前类是内部类，那么通过此方法可以得到当前类的外包类。
	 * 
	 * @return 当前类的外包类。
	 */
	public Class<?> getOuterClass() {
		if (Modifier.isStatic(clazz.getModifiers()))
			return null;
		String name = clazz.getName();
		int pos = name.lastIndexOf('$');
		if (pos == -1)
			return null;
		name = name.substring(0, pos);
		try {
			return Class.forName(name);
		} catch (ClassNotFoundException e) {
			return null;
		}
	}

	/**
	 * 得到实例化对象的方式。
	 * 
	 * @param needCast
	 *            是否需要自动类型转换。
	 * 
	 * @param args
	 *            要实例化当前类型的对象所需要的参数。
	 * @return 当前类型实例化对象的方式。
	 * 
	 * @throws FruitingException
	 *             当不能得到实例化对象的方式时出现。
	 * 
	 * @see org.atlantis.grosbeak.lang.fruit.Fruiting
	 */
	public Fruiting<T> getFruitint(boolean needCast, Object... args)
			throws FruitingException {
		return new MirrorFruiting<T>(this, needCast, args).getFruiting();
	}

	/**
	 * 实例化当前类型的一个对象，默认会自动转换类型。
	 * 
	 * @param args
	 *            实例化时需要的参数。
	 * @return 新对象。
	 * 
	 * @throws FruitingException
	 *             当不能实例化对象时出现。
	 * 
	 * @see org.atlantis.grosbeak.lang.fruit.MirrorFruiting#fruit()
	 */
	public T fruit(Object... args) throws FruitingException {
		return new MirrorFruiting<T>(this, true, args).fruit();
	}

	/**
	 * 实例化当前类型的一个对象，默认不会自动转换类型。
	 * 
	 * @param args
	 *            实例化时需要的参数。
	 * @return 新对象。
	 * @throws FruitingException
	 *             当不能实例化对象时出现。
	 */
	public T fruitWithoutCast(Object... args) throws FruitingException {
		return new MirrorFruiting<T>(this, false, args).fruit();
	}

	/**
	 * 根据字段名，得到一个字段的注入方式。优先使用Setter，如果找不到Setter就直接字段注入，如果还找不到字段就抛出异常。
	 * 
	 * @param fieldName
	 *            字段名。
	 * @return 字段的注入方式。
	 * @throws FailToMirrorException
	 *             当不能获得字段注入方式时出现。
	 */
	public Injecting getInjecting(String fieldName)
			throws FailToMirrorException {
		// 首先查找所有的Setter方法，是为了避免用户有Setter方法但是却没有这个字段的问题。而下面直接查找所有Setter方法就可以忽略字段。
		Method methods[] = tryToFindSetters(fieldName);
		if (methods.length == 1) {
			return new SetterInjector(methods[0]);
		} else {
			try {
				Field field = getField(fieldName);
				try {
					Method setter = getSetter(field);
					return new SetterInjector(setter);
				} catch (Exception e) {
					return new FieldInjector(field);
				}
			} catch (Exception e1) {
				throw Exceptions.makeThrow(FailToMirrorException.class,
						"Fail to get injecting for '%s.%s', because [%s]",
						clazz.getName(), fieldName, e1.getMessage());
			}
		}
	}

	/**
	 * 根据字段名，为指定对象注入值。
	 * 
	 * @param target
	 *            需要进行注入的对象。
	 * @param value
	 *            需要注入的值。
	 * @param fieldName
	 *            需要注入值的字段名。
	 * @throws FailToInjectException
	 *             当不能注入时出现。
	 */
	public void inject(Object target, Object value, String fieldName)
			throws FailToInjectException {
		try {
			Injecting inject = getInjecting(fieldName);
			inject.inject(target, value);
		} catch (Exception e) {
			throw Exceptions.makeThrow(FailToInjectException.class,
					"Fail to set '%s' to '%s.%s', because [%s].", value, clazz
							.getName(), fieldName, e.getMessage());
		}
	}

	/**
	 * 将一组对象转换成一组类型。
	 * 
	 * @param args
	 *            一组对象。
	 * @return 一组对象中每个对象的类型的数组。
	 */
	public static Class<?>[] evalToTypes(Object... args) {
		Class<?>[] types = new Class<?>[args.length];
		int i = 0;
		for (Object obj : args)
			types[i++] = (null == obj) ? Object.class : obj.getClass();
		return types;
	}

	/**
	 * 将一个Object[]数组，转换成一个具有指定类型和维度的数组。例如：
	 * 
	 * <pre>
	 * Object[] obj = new Object[]{"a", "b", "c"};
	 * 那么Mirror.evalArgToArray(obj);返回的结果就是一个String类型的数组，String[]{"a", "b", "c"};
	 * </pre>
	 * 
	 * 所以说这个方法其实就是把产生一个新的数组，新的数组的类型就是原始数组中元素的类型（当然原始数组中
	 * 的类型必须都相同，就像上面那个例子中都是String类型），新的数组的长度也是原始数组的长度，当然原始数组
	 * 中的所有元素也都按顺序填充到新的数组中了。<br>
	 * 但是如果原始数组中存在不同类型的元素，返回的就还是原始数组。如：
	 * 
	 * <pre>
	 * Object[] obj = new Object[]{"a", 1, true};
	 * 那么Mirror.evalArgToArray(obj);返回的就还是Object[]{"a", 1, true}。
	 * </pre>
	 * 
	 * @param args
	 *            需要转换的数组。
	 * @return 转换后的新数组。如果原数组中的元素类型存在不同，那么返回原数组。
	 */
	public static Object evalArgToArray(Object... args) {
		if (null == args || args.length == 0)
			return null;
		if (null == args[0])
			return null;
		Object result = null;

		// 检查args数组中的元素的类型是否都相同
		Class<?> type = null;
		for (Object arg : args) {
			if (null == arg)
				break;
			if (null == type) {
				type = arg.getClass();
				continue;
			}
			if (arg.getClass() != type) {
				type = null;
				break;
			}
		}

		// 如果args数组中元素的类型都相同
		if (type != null) {
			result = Array.newInstance(type, args.length);
			for (int i = 0; i < args.length; i++) {
				Array.set(result, i, args[i]);
			}
			return result;
		}
		return args;
	}

	/**
	 * 创建一个指定类型的空白数组。
	 * 
	 * @param clazzs
	 *            数组类型。
	 * @return 长度为0的空白数组。
	 */
	public static Object[] blankArray(Class<?> clazz) {
		return (Object[]) Array.newInstance(clazz, 0);
	}

	/**
	 * 用来匹配方法所需要的参数和调用这个方法所传入的参数在个数和类型（可以自动转换类型）上是否匹配。
	 * 
	 * @param paramTypes
	 *            方法所需要的参数类型数组。
	 * @param argTypes
	 *            调用方法传入的参数类型数组。
	 * @return 匹配类型。
	 * 
	 * @see org.atlantis.grosbeak.lang.MatchType
	 */
	public static MatchType matchParamTypes(Class<?>[] paramTypes,
			Class<?>[] argTypes) {
		int length = (argTypes == null) ? 0 : argTypes.length;
		if (length == 0 && paramTypes.length == 0)
			return MatchType.YES;
		if (paramTypes.length == length) {
			boolean mark = true;
			for (int i = 0; i < length; i++)
				if (paramTypes[i] == argTypes[i]
						|| paramTypes[i].isAssignableFrom(argTypes[i])) {
					continue;
				} else if (Mirror.me(argTypes[i]).canCastTo(paramTypes[i])) {
					mark = false;
					continue;
				} else {
					return MatchType.NO;
				}
			return mark ? MatchType.YES : MatchType.MAYBE;
		}
		return MatchType.NO;
	}

	/**
	 * 进行批量类型转换，把args中的值转换成types中的对应位置的类型。
	 * 
	 * @param types
	 *            需要转换到的类型。
	 * @param args
	 *            需要转换的值。
	 * @return 转换后的数组。如果转换失败则返回原数组。
	 */
	public static Object[] batchCast(Class<?>[] types, Object[] args) {
		Object[] result = new Object[args.length];
		if (types.length == args.length) {
			for (int i = 0; i < types.length; i++) {
				try {
					result[i] = Castors.me().castTo(args[i], types[i]);
				} catch (Exception e) {
					return args;
				}
			}
		}
		return result;
	}

	/**
	 * 用来匹配方法所需要的参数和调用这个方法所传入的参数在个数和类型（可以自动转换类型）上是否匹配。
	 * 
	 * @param paramTypes
	 *            方法所需要的参数类型数组。
	 * @param args
	 *            调用方法传入的参数数组。
	 * @return 是否匹配。
	 * 
	 * @see #matchParamTypes(Class[], Class[])
	 */
	public static MatchType matchParamTypes(Class<?>[] paramTypes,
			Object... args) {
		return matchParamTypes(paramTypes, evalToTypes(args));
	}

	/*
	 * 判断该字段是否需要获取，如果有static，final修饰符的字段则不需要获取，this也不需要获取。
	 * 如果要忽略则返回true，否则返回false。
	 */
	private static boolean isIgnoreField(Field field) {
		if (Modifier.isStatic(field.getModifiers()))
			return true;
		if (Modifier.isFinal(field.getModifiers()))
			return true;
		if (Strings.startsWith(field.getName(), "this$"))
			return true;
		return false;
	}

	/**
	 * 得到方法的参数类型数组的字符串描述。
	 * 
	 * @param paramTypes
	 *            方法的参数类型数组。
	 * @return 描述。
	 */
	public static String getParamsDesc(Class<?>[] paramTypes) {
		StringBuilder sb = new StringBuilder();
		sb.append('(');
		for (Class<?> paramType : paramTypes)
			sb.append(getTypeDesc(paramType));
		sb.append(')');
		return sb.toString();
	}

	/**
	 * 得到方法的字符串描述。
	 * 
	 * @param method
	 *            方法。
	 * @return 描述。
	 */
	public static String getMethodDesc(Method method) {
		return getParamsDesc(method.getParameterTypes())
				+ getTypeDesc(method.getReturnType());
	}

	/**
	 * 得到构造方法的字符串描述。
	 * 
	 * @param cons
	 *            构造方法。
	 * @return 描述。
	 */
	public static String getConstructorDesc(Constructor<?> cons) {
		return getParamsDesc(cons.getParameterTypes()) + "V";
	}

	/**
	 * 得到类型的描述符。例如int用I表示，long用L表示，void用V表示等。
	 * 
	 * @param c
	 *            类型。
	 * @return 描述。
	 */
	public static String getTypeDesc(Class<?> c) {
		if (c.isPrimitive()) {
			if (c == void.class)
				return "V";
			else if (c == int.class)
				return "I";
			else if (c == long.class)
				return "L";
			else if (c == byte.class)
				return "B";
			else if (c == short.class)
				return "S";
			else if (c == float.class)
				return "F";
			else if (c == double.class)
				return "D";
			else if (c == char.class)
				return "C";
			else
				// 当c == boolean.class时
				return "Z";
		}
		StringBuilder sb = new StringBuilder();
		if (c.isArray()) {
			return sb.append('[').append(getTypeDesc(c.getComponentType()))
					.toString();
		}
		return sb.append("").append(getPath(c)).append(';').toString();
	}

	/**
	 * 获得一个类型的包的路径。如：
	 * 
	 * <pre>
	 * org.atlantis.grosbeak.lang所对应的路径就是：org/atlantis/grosbeak/lang
	 * </pre>
	 * 
	 * @param c
	 *            类型。
	 * @return 类型所对应的路径。
	 */
	public static String getPath(Class<?> c) {
		return c.getName().replace('.', '/');
	}

	/**
	 * 获取一个类的泛型数组。如果这个类没有泛型，那么返回null。
	 * 
	 * @param clazz
	 *            需要得到其泛型的类。
	 * @return 泛型数组（因为该类可能有多个泛型，如：Map<String, String>就有两个泛型参数）。
	 */
	public static Type[] getClassTypes(Class<?> clazz) {
		Type superclass = clazz.getGenericSuperclass();
		if (superclass instanceof ParameterizedType)
			return ((ParameterizedType) superclass).getActualTypeArguments();
		return null;
	}

	// 字段在Class字节码中的正则表达式
	private static final Pattern FP = Pattern.compile("(<)(.+)(>)");

	/**
	 * 获取一个字段的泛型参数数组，如果这个字段没有泛型，则返回空数组。
	 * 
	 * @param field
	 *            字段。
	 * @return 该字段的泛型参数数组。
	 */
	public static Class<?>[] getGenericTypes(Field field) {
		String gts = field.toGenericString();
		Matcher matcher = FP.matcher(gts);
		if (matcher.find()) {
			String s = matcher.group(2);
			String[] ss = Strings.spliteIgnoreBlank(s);
			if (ss.length > 0) {
				Class<?>[] re = new Class<?>[ss.length];
				try {
					for (int i = 0; i < ss.length; i++) {
						String className = ss[i];
						if (className.startsWith("?"))
							re[i] = Object.class;
						else {
							int pos = className.indexOf('<');
							if (pos < 0)
								re[i] = Class.forName(className);
							else
								re[i] = Class.forName(className.substring(0,
										pos));
						}
					}
					return re;
				} catch (ClassNotFoundException e) {

				}
			}
		}
		return new Class<?>[0];
	}

	/**
	 * 判断一个类型是否是一个泛型，如果是则返回声明此类型的类或接口。如果不是则返回本身。
	 * 
	 * @param type
	 *            要判断的指定类型。
	 * @return 如果指定类型是一个泛型，那么返回声明此类型的类或接口，如果不是则返回本身。
	 */
	public static Type getClassRawType(Type type) {
		if (type instanceof ParameterizedType)
			return ((ParameterizedType) type).getRawType();
		return type;
	}

	/**
	 * 判断当前对象是否为指定类型。精确匹配，只能是完全相同的类型才能匹配，即使是父类和接口也不会匹配。
	 * 
	 * <pre>
	 * Mirror.me(String.class).is(String.class)是true；
	 * Mirror.me(String.class).is(CharSequence.class)是false，尽管CharSequence是String的父类。
	 * </pre>
	 * 
	 * @param type
	 *            类型。
	 * @return 是否匹配。
	 * 
	 * @see #as(Class)
	 * @see #is(String)
	 */
	public boolean is(Class<?> type) {
		if (null == type)
			return false;
		if (clazz == type)
			return true;
		return false;
	}

	/**
	 * 判断当前对象是否为指定类型。精确匹配，只能是完全相同的类型才能匹配，即使是父类和接口也不会匹配。如：
	 * 
	 * <pre>
	 * Mirror.me(String.class).is("String")是true；
	 * Mirror.me(String.class).is("CharSequence")是false，尽管CharSequence是String的父类。
	 * </pre>
	 * 
	 * @param type
	 *            类型名称，如String。
	 * @return 是否匹配。
	 * 
	 * @see #as(Class)
	 * @see #is(Class)
	 */
	public boolean is(String className) {
		return clazz.getName().equals(className);
	}

	/**
	 * 判断指定类型是否为当前类型的父类或接口，或是相同类型。如：
	 * 
	 * <pre>
	 * Mirror.me(String.class).as(CharSequence.class)是true。
	 * Mirror.me(String.class).as(String.class)也是true。
	 * </pre>
	 * 
	 * @param type
	 *            指定类型。
	 * @return 当前类型是否为指定类型的子类或接口实现类。
	 * 
	 * @see #is(Class)
	 * @see #is(String)
	 */
	public boolean as(Class<?> type) {
		return type.isAssignableFrom(clazz);
	}

	/**
	 * 当前对象是否为字符串。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isString() {
		return is(String.class);
	}

	/**
	 * 当前对象是否和String继承相同的父类（即CharSequence）。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean asString() {
		return as(CharSequence.class);
	}

	/**
	 * 当前对象是否是一个字符。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isChar() {
		return is(Character.class) || is(char.class);
	}

	/**
	 * 当前对象是否是一个枚举。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isEnum() {
		return clazz.isEnum();
	}

	/**
	 * 当前对象是否是一个布尔类型的值。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isBoolean() {
		return is(Boolean.class) || is(boolean.class);
	}

	/**
	 * 当前对象是否是一个浮点数。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isFloat() {
		return is(Float.class) || is(float.class);
	}

	/**
	 * 当前对象是否是一个双精度浮点数。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isDouble() {
		return is(Double.class) || is(double.class);
	}

	/**
	 * 当前对象是否是一个整形数。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isInt() {
		return is(Integer.class) || is(int.class);
	}

	/**
	 * 当前对象是否是一个整数。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isIntLike() {
		return isInt() || isLong() || isShort() || isByte()
				|| is(BigDecimal.class);
	}

	/**
	 * 当前对象是否是一个长整形。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isLong() {
		return is(Long.class) || is(long.class);
	}

	/**
	 * 当前对象是否是一个短整形。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isShort() {
		return is(Short.class) || is(short.class);
	}

	/**
	 * 当前对象是否是一个字节形。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isByte() {
		return is(Byte.class) || is(byte.class);
	}

	/**
	 * 当前对象是否是一个数字。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isNumber() {
		return as(Number.class) || clazz.isPrimitive() && !is(Boolean.class)
				&& !is(char.class);
	}

	/**
	 * 当前对象是否是一个原始类型的数字（包括int、long、short、float、double、byte）。
	 * 
	 * @return 如果是原始类型的数字就返回true，否则返回false。
	 */
	public boolean isPrimitiveNumber() {
		return isInt() || isLong() || isShort() || isFloat() || isDouble()
				|| isByte();
	}

	/**
	 * 当前对象是否是一个小数。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isDecimal() {
		return isFloat() || isDouble();
	}

	/**
	 * 当前对象是否表示日期或时间。
	 * 
	 * @return 如果是则返回true，否则返回false。
	 */
	public boolean isDateTimeLike() {
		return as(Calendar.class) || as(java.sql.Date.class)
				|| as(java.sql.Timestamp.class) || as(java.util.Date.class);
	}
}
